import { _decorator, Component, Node, Vec3 } from "cc";
import { RoadPoint } from "./RoadPoint";
const { ccclass, property } = _decorator;

const tempVec = new Vec3();

@ccclass("Car")
export class Car extends Component {
    @property
    maxSpeed = 0.2;

    private currentRoadPoint: RoadPoint = null;
    private pointA = new Vec3();
    private pointB = new Vec3();
    private currentSpeed = 0;
    private isMoving = false;
    private offset = new Vec3();

    // 弯路旋转相关变量
    private originRotation = 0;
    private targetRotation = 0;
    private centerPoint = new Vec3();
    private rotationMeasure = 0;
    private acceleration = 0.2;

    public update(dt: number) {
        if (this.isMoving) {
            this.offset.set(this.node.worldPosition);

            this.currentSpeed += this.acceleration * dt;
            if (this.currentSpeed > this.maxSpeed) {
                this.currentSpeed = this.maxSpeed;
            }

            if (this.currentSpeed <= 0.001) {
                this.isMoving = false;
            }

            switch (this.currentRoadPoint.moveType) {
                case RoadPoint.RoadMoveType.Bend:
                    //#region 小车旋转处理
                    const offsetRotation = this.targetRotation - this.originRotation;
                    const currentRotation = this.Convert2OneSideAngle(this.node.eulerAngles.y);
                    let nextStation =
                        currentRotation -
                        this.originRotation +
                        this.currentSpeed *
                            this.rotationMeasure *
                            (this.targetRotation > this.originRotation ? 1 : -1);
                    // 容错处理
                    if (Math.abs(nextStation) > Math.abs(offsetRotation)) {
                        nextStation = offsetRotation;
                    }

                    const target = nextStation + this.originRotation;
                    tempVec.set(0, target, 0);
                    this.node.eulerAngles = tempVec;
                    //#endregion

                    //#region 小车运动轨迹处理
                    // 使用三角函数绕Y轴旋转计算
                    Vec3.rotateY(
                        this.offset,
                        this.pointA,
                        this.centerPoint,
                        this.Radian2Angle(nextStation)
                    );
                    //#endregion
                    break;

                default:
                    const z = this.pointB.z - this.pointA.z;
                    if (z !== 0) {
                        if (z > 0) {
                            this.offset.z += this.currentSpeed;
                            if (this.offset.z > this.pointB.z) {
                                this.offset.z = this.pointB.z;
                            }
                        } else {
                            this.offset.z -= this.currentSpeed;
                            if (this.offset.z < this.pointB.z) {
                                this.offset.z = this.pointB.z;
                            }
                        }
                    } else {
                        const x = this.pointB.x - this.pointA.x;
                        if (x > 0) {
                            this.offset.x += this.currentSpeed;
                            if (this.offset.x > this.pointB.x) {
                                this.offset.x = this.pointB.x;
                            }
                        } else {
                            this.offset.x -= this.currentSpeed;
                            if (this.offset.x < this.pointB.x) {
                                this.offset.x = this.pointB.x;
                            }
                        }
                    }
                    break;
            }
            this.node.setWorldPosition(this.offset);
            Vec3.subtract(tempVec, this.pointB, this.offset);
            if (tempVec.length() <= 0.1) {
                this.ArrivalStation();
            }
        }
    }

    public SetEntry(entry: Node) {
        this.node.setWorldPosition(entry.worldPosition);
        this.currentRoadPoint = entry.getComponent(RoadPoint);
        if (!this.currentRoadPoint) {
            console.warn("There is no RoadPoint in" + entry.name);
            return;
        }

        this.pointA.set(entry.worldPosition);
        this.pointB.set(this.currentRoadPoint.nextStation.worldPosition);

        const z = this.pointB.z - this.pointA.z;
        if (z !== 0) {
            if (z < 0) {
                this.node.eulerAngles = new Vec3();
            } else {
                this.node.eulerAngles = new Vec3(0, 180, 0);
            }
        } else {
            const x = this.pointB.x - this.pointA.x;
            if (x > 0) {
                this.node.eulerAngles = new Vec3(0, 270, 0);
            } else {
                this.node.eulerAngles = new Vec3(0, 90, 0);
            }
        }
    }

    public StartRunning() {
        if (this.currentRoadPoint) {
            this.isMoving = true;
            this.currentSpeed = 0;
            this.acceleration = 0.2;
        }
    }

    public StopRunning() {
        this.acceleration = -0.3;
    }

    private ArrivalStation() {
        console.log("到站了");
        this.pointA.set(this.pointB);
        this.currentRoadPoint = this.currentRoadPoint.nextStation.getComponent(RoadPoint);
        if (this.currentRoadPoint.nextStation) {
            this.pointB.set(this.currentRoadPoint.nextStation.worldPosition);

            if (this.currentRoadPoint.moveType === RoadPoint.RoadMoveType.Bend) {
                if (this.currentRoadPoint.clockwise) {
                    // 顺时针
                    this.originRotation = this.Convert2OneSideAngle(this.node.eulerAngles.y);
                    this.targetRotation = this.originRotation - 90;

                    // 当点B在A的右上角或者左下角时 绕着旋转的中心点的x是点B的x，y是点A的y 反之则相反
                    if (
                        (this.pointB.z < this.pointA.z && this.pointB.x > this.pointA.x) ||
                        (this.pointB.z > this.pointA.z && this.pointB.x < this.pointA.x)
                    ) {
                        this.centerPoint.set(this.pointB.x, 0, this.pointA.z);
                    } else {
                        this.centerPoint.set(this.pointA.x, 0, this.pointB.z);
                    }
                } else {
                    // 逆时针
                    this.originRotation = this.Convert2OneSideAngle(this.node.eulerAngles.y);
                    this.targetRotation = this.originRotation + 90;

                    // 当点B在A的右上角或者左下角时 绕着旋转的中心点的x是点B的x，y是点A的y 反之则相反
                    if (
                        (this.pointB.z > this.pointA.z && this.pointB.x > this.pointA.x) ||
                        (this.pointB.z < this.pointA.z && this.pointB.x < this.pointA.x)
                    ) {
                        this.centerPoint.set(this.pointB.x, 0, this.pointA.z);
                    } else {
                        this.centerPoint.set(this.pointA.x, 0, this.pointB.z);
                    }
                }

                Vec3.subtract(tempVec, this.pointA, this.centerPoint);
                const r = tempVec.length();
                this.rotationMeasure = 90 / ((Math.PI * r) / 2);
            }
        } else {
            console.log(1);
            this.isMoving = false;
            this.currentRoadPoint = null;
        }
    }

    private Convert2OneSideAngle(value: number) {
        let result = value;
        // 如果这个角度是负数，就加360变成正数的角度
        return result <= 0 ? result + 360 : result;
    }

    private Radian2Angle(radius: number) {
        return (radius * Math.PI) / 180;
    }
}
